
*			  ==========================================
*						     Stata公开课 
*  
*                           软件及计量基础   
*             ==========================================

*                    	 主讲人：候丹丹
*                   	 主办方：连享会（www.lianxh.cn）
*           课程主页：https://gitee.com/lianxh/stataopen
*                     :: 课件下载，答疑等 ::

*			       ============================
*					 	 第三讲 Stata程序   
*                  ============================

**-注意：执行后续命令之前，请先执行如下几条命令

  global Path 	"`c(sysdir_stata)'ado\personal\open3_program"  //定义课程路径 
  global D		"$Path\data"		//范例数据
  global Ado  	"$Path\ado"			//自己编写的程序文件
  adopath + 	"$Ado"
  cd "$D"     
  set scheme s2color  //设定图形格式为默认格式
  
  *-note: 
  /*	`c(sysdir_stata)'是一个暂元，里面存放了Stata的安装路径：
	输入 sysdir 后显示的第一个文件路径。
	例如, 我的 stata17存放于D盘study文件下, 
	所以, `c(sysdir_stata)' = D:\study\Stata17\     	*/

	

  * ===== 学习过程遇到问题怎么办？====
  *
  * ❓ 提问前，先用 -lianxh- 或 -songbl- 命令搜索相关资料和推文
      ssc install lianxh,replace
	  ssc install songbl,replace
      lianxh DID 倍分法
      songbl 面板
	  help lianxh 
      help songbl	  
  * ❓ 亦可，前往课程主页 https://gitee.com/arlionn/PX --> wiki 
  *   查看 FAQs，通常都能找到答案。 
  *
  
*----------------
*   本讲目录  
*----------------
* 3.1 Stata程序简介
* 3.2 单值
* 3.3 暂元
* 3.4 循环语句




 
*			  ==========================================
*						     Stata公开课 
*  
*                           软件及计量基础   
*             ==========================================

*                    	 主讲人：候丹丹
*                   	 主办方：连享会（www.lianxh.cn）
*           课程主页：https://gitee.com/lianxh/stataopen
*                     :: 课件下载，答疑等 ::

*			       ============================
*					 	 第三讲 Stata程序   
*                  ============================
*					    -3.1- Stata程序简介
*  
*-3.1.1- Stata程序的基本结构

     program define myprog
     version 17
        dis "快乐学习!"
     end
	 
	 myprog
	 
	/* 几点注意：① program define 和 end 组合使用
				 ② 程序名称可包含字母和数字，不能和现有程序重名 */
	
*-3.1.2- Stata程序的执行 

	*-执行方式一：Crtl+D
	
	*-执行方式二：Crtl+R  无输出执行
	program define mynike
	version 8.0
	dis in red "Just do it! "
	end  
       
	mynike 
	
	*-执行方式三：ado文档执行

	adopath + "$Ado" 
	myprog
	adopath - 7  //删除屏幕显示的第 7 条路径
    
    *-说明：
    *   (1) 这种执行方式与stata官方命令完全相同；
    *   (2) 对于需要经常执行的命令，采用这种方式很好；  
 
*-3.1.3- Stata程序的管理  

	program dir          //查找内存中的程序
	program drop mynike	//删除内存中调入的程序，但不影响硬盘中存储的文件 
	mynike               //错误信息，因为程序已不在内存中
	
	*-修改程序
	*-	方式1：修改硬盘上的程序文件
	doedit "$Ado\myprog.ado"  
	*-	方式2：修改内存中的程序
	*   	(1) 先将旧版本从内存中清除(program drop)，
	*      	 	然后再调入新定义的程序
	program drop myprog
	program define myprog
	version 8.0
	dis in red "快乐学习! hahaha! " 
	end
	
	*   	(2) 更为合理的定义方法：      
	capture	program drop mynike        // 新增语句
	program define mynike
      version 8.0
      dis in red "Just do it! hahaha! " 
	end  
          
	mynike
 
*-3.1.4 Stata编写程序的小技巧

	*-①	避免程序因错误而中断
	sysuse auto, clear
	drop prcie              // 发生错误，报错，停止执行
	sum mpg
	
	capture drop prcie      // 发生错误，不报错，不停止执行
	sum mpg
	dis _rc                 // -help _rc- 报错代码的返回值
	
	capture drop price      // 正确! 不报错
	dis _rc                 // 注意该值的变化	
	
	cap noisily drop prcie  // 发生错误，报错，不停止执行
	sum mpg	
	
	*-②	避免数据在程序执行过后有所变动     -preserve-
	sysuse auto, clear
	preserve                      // 备份当前状态 s1
		keep price weight foreign
		drop if price > 10000
		sum 
		save auto_new.dta, replace
	restore                       // 恢复到状态 s1
	sum  
	use auto_new.dta,clear
	
	*-举一个例子
	sysuse auto.dta,clear
	reg price weight length
	est store ols1
	preserve
		gen lnprice=ln(price)
		gen lnweight=ln(weight)
		gen lnlength=ln(length)
		reg lnprice lnweight lnlength
		est store ols2
	restore
	esttab ols1 ols2, stat(N r2)
		

*-3.1.5- 创建一个新命令：ado文档
	 capture program drop log2
	 program define log2
	 version 17
	 syntax varlist [if] [in]
	 foreach var in `varlist' {
        gen ln`var' = ln(`var') `if' `in'
    } 
	 end
	 
	 sysuse auto,clear	 
	 log2 price weight length
 		  
*-更多关于ado文档编写的技巧 
	*-Stata程序：10 分钟快乐编写 ado 文件
	view browse "https://www.lianxh.cn/news/a9d7de7ff1d80.html"
	*-Stata：编写ado文件自动化执行常见任务
	view browse "https://www.lianxh.cn/news/776e42fc6ecd4.html"
 
 
 
 
 
 
 
 
*			  ==========================================
*						     Stata公开课 
*  
*                           软件及计量基础   
*             ==========================================

*                    	 主讲人：候丹丹
*                   	 主办方：连享会（www.lianxh.cn）
*           课程主页：https://gitee.com/lianxh/stataopen
*                     :: 课件下载，答疑等 ::

*			       ============================
*					 	 第三讲 Stata程序   
*                  ============================
*					         -3.2- 单值
*  
*-3.2.1- 单值简介
	sysuse auto, clear
	sum price
	reg price wei len
	
	*存放数值
	scalar a = 3
	scalar b = ln(a) + 3^a
	dis a
	dis b
	
	*存放字符串
	scalar s1 = "hello, Arlion"
	scalar s2 = substr(s1,1,5)   // 单值的引用很简单
	dis s1
	dis s2
	
*-3.2.2 执行命令后的单值
	
	  *- Stata 命令分为三种类型：
  
     * (1) r-class  与模型估计无关的命令； 如，summary pwcorr
     * (2) e-class  与模型估计有关的命令； 如，regress
     * (3) s-class  其它命令；             如，list
     * (4) c-class  存储系统参数

	*- 显示留存值的方法：
     * r-class:  return  list
     * e-class:  ereturn list
     * s-class:  sreturn list
     * c-class:  creturn list

	*- 留存值分为四种类型：
     * 单值：  如，r(mean), r(max), r(N), e(r2), e(F)
     * 矩阵：  如，e(b), e(V)
     * 暂元：  如，e(cmd), e(depvar)
     * 函变量：如，e(sample)
	 
	sysuse auto,clear 
	sum price 
	return list
    dis r(N)
	dis r(mean)
	gen price_demean = price-r(mean)  //去中心化，生成交乘项
	
	reg price wei len 
	ereturn list
	dis e(N)       //样本数
	dis e(r2)      //R2
	matrix list e(b)  //系数矩阵	
	dis _b[wei]    //变量的估计系数
	dis _b[_cons]  //常数项

	gen y_hat=_b[_cons]+_b[wei]*wei+_b[len]*len  //估计y的拟合值

*-更多关于单值的介绍
	*-statsby: 不用循环语句的循环
    view browse "https://www.lianxh.cn/news/73bd1e84f077b.html"	
	*-Stata33讲-P1: 单值_连玉君 
	view browse "https://www.bilibili.com/video/BV1MT4y1u7o4?vd_source=f5ca6d1986d0bb0043d9dd1587d2e2b0"
	
	
 
 
 
 
 
 
 
 
 
 
 
 
 
*			  ==========================================
*						     Stata公开课 
*  
*                           软件及计量基础   
*             ==========================================

*                    	 主讲人：候丹丹
*                   	 主办方：连享会（www.lianxh.cn）
*           课程主页：https://gitee.com/lianxh/stataopen
*                     :: 课件下载，答疑等 ::

*			       ============================
*					 	 第三讲 Stata程序   
*                  ============================
*					         -3.3- 暂元
* 
*-3.3.1- 局部暂元 (local) 

	help local
	
	*-局部暂元的定义与引用
		local x 2
		dis `x' 
	
	*-局部暂元的基本功能
		
		*- 存放数字

		local x=2+2
		dis `x'
		
		local x 2+2		//计算器功能
		dis `x'
		
		local x 2+2
		dis "`x'" 
		
		*-存放文字
		local x "学习Stata 努力写论文"
		dis "`x'"
		
		*-存放变量名称
		sysuse auto, clear
		local xx "price weight mpg foreign"
		sum `xx'
		reg `xx'
		
		*-提取变量标签
		sysuse auto,clear 
		des2
		local lab: var label foreign  // 暂元名称为lab，保存了foreign变量的标签
		dis "`lab'" // 列印变量标签
		label var mpg  "`lab'"  // 将foreign变量的标签赋给mpg变量
		des2 foreign mpg
		
		*-提取变量值标签
		sysuse auto,clear 
		local lab: value label foreign // 暂元名称为 lab，保存了 foreign 变量的值标签
		dis "`lab'" // 列印变量值标签
		label value  rep78 "`lab'"
		des2 foreign rep78
		
*-3.3.2- 全局暂元 (global)  

	*- 定义和引用
     global aa "This is my first global!"      
     dis "$aa"

     global x1 = 5
     global x2 = 2^$x1
     dis $x2
	 
*-3.3.3- 在回归中的使用技巧 

     sysuse auto, clear
     local  robust ",robust"    //公共选项
	 global y "price"
	 global x "weight"
     global control "mpg rep78 headroom trunk length" 
	 
	 sum $y $x $control
	 
	 *-column(1)	
	 reg $y $x `robust'  
	 //等价于reg price weight , r
     est store m1
	 
	 *-column(2)
     reg $y $x $control `robust'  
	 //等价于 reg price weight mpg rep78 headroom trunk length, r
     est store m2
	
	 *-column(3)
     reg $y $x $control i.foreign `robust'  
	 //等价于 reg price weight mpg rep78 headroom trunk length i.foreign, r
     est store m3
	 
	 local s "using mytable.rtf"
	 local mm "m1 m2 m3"
     esttab `mm' `s', nogap s(N r2_a) addnote("`robust'") replace	 
	 
*-更多关于暂元的用法
	*-Stata编程：暂元，local！暂元，local！
    view browse "https://www.lianxh.cn/news/4d57e771feba7.html"
	






*			  ==========================================
*						     Stata公开课 
*  
*                           软件及计量基础   
*             ==========================================

*                    	 主讲人：候丹丹
*                   	 主办方：连享会（www.lianxh.cn）
*           课程主页：https://gitee.com/lianxh/stataopen
*                     :: 课件下载，答疑等 ::

*			       ============================
*					 	 第三讲 Stata程序   
*                  ============================
*					  -3.4- 循环语句和条件语句

*-3.4.1- while语句: 条件循环

    local j = 0
    while `j'<5{
       dis  `j'
       local j = `j'+1
    }
	
	doedit "$Ado\surprise.ado"
	
*-3.4.2- forvalues语句：数字的循环
	
	/*	编程语法
	forvalues i = range {
     command
	}
	*/

    forvalues i = 1(2)14{
       dis  `i'
    }
	
	*-示例：分行业回归分析	
	sysuse nlsw88, clear
	global yx "wage hours collgrad ttl_exp"
    forvalues i = 1/4{        //公差为 1 的等差数列
	  dis "Occupation == " `i' 
      reg $yx if occupation==`i'
	  est store m`i'
    }
	esttab m1 m2 m3 m4, nogap s(r2_a N)
	tab occu
	
*-3.4.3- foreach语句: 变量、暂元、文件等的循环

	*-3.4.3.1- 变量循环
	
		/*	编程语法
		foreach var of varlist {
		command
		}
		*/
		
		*-示例1：对变量进行批量取对数
	sysuse auto, clear
	foreach var of varlist price-length {
		gen ln`var' = ln(`var')
		}
		
		*-示例2：对变量进行批量缩尾
	sysuse nlsw88, clear
	local vars "wage hours ttl_exp grade"
	foreach v of varlist `vars'{
		winsor `v' , gen(`v'_w) p(0.01)
         }      
	d *_w   	
	
	winsor2 wage hours ttl_exp grade, cuts(0.5 99.5) replace
	
	*-3.4.3.2- 文件循环
	
		/* 编程语法
		foreach i in anylist{
		command
		}
		*/
	
		*-示例：将多个txt文件转换为dta格式
	type Audi.txt
	type Benz.txt 
	type BMW.txt

	global vlist "id year invest market stock"
	foreach file in  Audi Benz BMW{
		insheet $vlist using `file'.txt,clear
		save `file'.dta, replace 
         }
		 
		*-追加样本
	use Audi.dta, clear
		foreach file in  Benz BMW{
		append using `file'.dta
         }
         list
		 
	*-3.4.3.3- 暂元循环
	
		/* 编程语法
		foreach var of local list {
		command
		}
		*/
	
	sysuse auto,clear
	local vars "price weight length"
	foreach cc of local vars{
		gen ln`cc' = ln(`cc') 
	}

*-3.4.4- if条件语句
	*-基本要求
	* (1) 语法格式
	*     CASE I:
	*        if (条件){
	*           执行命令
	*        }  
	*     CASE II:
	*        if (条件1){
	*           执行命令1
	*        } 
	*        esle if (条件2){
	*           执行命令2
	*        }      
	* (2) 左括弧 "{" 紧接着条件；右括弧 "}" 另起一行
	* (3) 条件判断可嵌套
	
	*-示例：判断并显示奇数和偶数
      forvalues x = 1/4 {
         if mod(`x', 2) {
           display "`x' is odd"
		   display "Haha!"
         }
         else {
           display "`x' is even"
         }
      }
	  

*-更多关于编程的学习资料
	lianxh 编程
	*-普林斯顿Stata教程(三) - Stata编程
	view browse "https://www.lianxh.cn/news/0c64a3d1b235d.html"
	



	
 
 